import numpy as np

from model.eigenface import EigenFace
from model.utils import load_data
import matplotlib.pyplot as plt

#交叉验证
def cross_validation(data):
    num_class, M, N = data.shape
    lables = np.array([c for c in range(num_class)])
    avg_acc = 0
    mask = np.array([i for i in range(M)])
    print('Cross validating...')
    for i in range(M):
        train_data = data[:, mask!=i]
        test_data = data[:, i]
        print('validating %d/%d...' % (i + 1, M))
        eigenface = EigenFace()
        eigenface.fit(train_data)
        acc = eigenface.evaluate(test_data, lables)
        avg_acc += acc
        print('accuracy: %f' % acc)
    avg_acc /= M
    print('average test accuracy: %f' % avg_acc)
    return avg_acc


#加载数据
data = load_data('./data/data.npz')
#展示数据
# fig = plt.figure(figsize=(11, 15))
# for i, faces in enumerate(data):
#     for j, face in enumerate(faces):
#         sub = fig.add_subplot(15, 11, i*11+j+1)
#         sub.axis('off')
#         sub.imshow(face.reshape(100, 100), cmap='gray')
# plt.show()

# 十折交叉验证
cross_validation(data)

# 显示特征脸
eigenface = EigenFace()
eigenface.fit(data)
eigenfaces = eigenface.eigenfaces
fig = plt.figure(figsize=(21, 45))
for i, faces in enumerate(eigenfaces):
    for j, face in enumerate(faces.T):
        sub = fig.add_subplot(15, 7, i*7+j+1)
        sub.set_title('eigenface class%d %d' % (i+1, j+1))
        sub.axis('off')
        sub.imshow(face.reshape(100, 100), cmap='gray')
plt.show()